package nl.ejvos.bgpgames.tictactoe.client;

import nl.ejvos.bgpgames.tictactoe.shared.ClickedMessage;
import nl.ejvos.bgpgames.tictactoe.shared.Constants;
import nl.ejvos.bgpgames.tictactoe.shared.EntireStateMessage;
import nl.ejvos.bgpgames.tictactoe.shared.RestartMessage;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.hu.bgp.framework.clientapi.Client;
import com.hu.bgp.framework.clientapi.ServerToClientMessage;
import com.hu.bgp.framework.util.FailureHandler;

/**
 * Game UI van boter, kaas & eieren.
 * 
 * @author ejvos
 */
public class TicTacToeClient extends Client implements FailureHandler
{
	final Button btnReset = new Button("Restart");
	final Image[][] imgTTT =
	{
		{
			new Image(), new Image(), new Image()
		},
		{
			new Image(), new Image(), new Image()
		},
		{
			new Image(), new Image(), new Image()
		}
	};
	final Grid grid = new Grid(3, 3);
	final Label lblResult = new Label();
	final HorizontalPanel hPanel = new HorizontalPanel();
	final VerticalPanel vPanel = new VerticalPanel();

	final String imgUrlAny = "/resources/tictactoe/images/any.jpeg";
	final String imgUrlMaybeCross = "/resources/tictactoe/images/maybecross.jpeg";
	final String imgUrlMaybeNought = "/resources/tictactoe/images/maybenought.jpeg";
	final String imgUrlCross = "/resources/tictactoe/images/cross.jpeg";
	final String imgUrlNought = "/resources/tictactoe/images/nought.jpeg";

	public void onModuleLoad2()
	{
		// set images
		for (int j = 0; j < 3; j++)
			for (int k = 0; k < 3; k++)
				grid.setWidget(j, k, imgTTT[j][k]);
		grid.setStyleName("ttt-Grid");
		grid.setWidth("192px");
		SimplePanel gridPanel = new SimplePanel();
		gridPanel.setWidget(grid);

		// Setup results and control area
		lblResult.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		//hPanel.add(btnReset);
		hPanel.add(lblResult);
		hPanel.setWidth("192px");

		// Add it to the html page
		vPanel.add(hPanel);
		vPanel.add(gridPanel);
		vPanel.getElement().setId("tttVPanel");

		// Setup UI click listeners
		btnReset.addClickHandler(new RestartHandler());
		for (int x = 0; x < 3; x++)
		{
			for (int y = 0; y < 3; y++)
			{
				TileEventHandler handler = new TileEventHandler(x, y);
				imgTTT[x][y].addClickHandler(handler);
				imgTTT[x][y].addMouseOverHandler(handler);
				imgTTT[x][y].addMouseOutHandler(handler);
				imgTTT[x][y].setUrl(imgUrlAny);
			}
		}
	}

	/**
	 * This method resets the game and lets cross start the next game.
	 */
	protected void handleMessage2(ServerToClientMessage message)
	{
		if (message instanceof EntireStateMessage)
		{
			EntireStateMessage state = (EntireStateMessage) message;
			if (state.getGameStatus() == Constants.gsNoughtPlaying)
			{
				lblResult.setText("Nought playing!");
			}
			else if (state.getGameStatus() == Constants.gsCrossPlaying)
			{
				lblResult.setText("Cross playing!");
			}
			else if (state.getGameStatus() == Constants.gsNobodyWon)
			{
				lblResult.setText("Draw!");
			}
			else if (state.getGameStatus() == Constants.gsNoughtWon)
			{
				lblResult.setText("Nought won!");
			}
			else if (state.getGameStatus() == Constants.gsCrossWon)
			{
				lblResult.setText("Cross won!");
			}

			int[][] tileStatus = state.getTileStatus();
			for (int x = 0; x < 3; x++)
			{
				for (int y = 0; y < 3; y++)
				{
					int ts = tileStatus[x][y];

					if (ts == Constants.tsAny)
					{
						imgTTT[x][y].setUrl(imgUrlAny);
					}
					else if (ts == Constants.tsCross)
					{
						imgTTT[x][y].setUrl(imgUrlCross);
					}
					else if (ts == Constants.tsNought)
					{
						imgTTT[x][y].setUrl(imgUrlNought);
					}
				}
			}
		}
	}

	private class RestartHandler implements ClickHandler
	{
		public void onClick(ClickEvent event)
		{
			sendMessageAndIgnoreOutcome(new RestartMessage(getUserUuid()));
		}
	}

	private class TileEventHandler implements ClickHandler, MouseOverHandler, MouseOutHandler
	{
		private int x, y;

		TileEventHandler(int x, int y)
		{
			this.x = x;
			this.y = y;
		}

		public void onClick(ClickEvent event)
		{
			ClickedMessage message = new ClickedMessage(getUserUuid(), x, y);
			sendMessageAndIgnoreOutcome(message);
		}

		public void onMouseOver(MouseOverEvent event)
		{
			/*
			 * service.getTileStatus(x, y, new
			 * ErrorHandlingCallback<Integer>(TicTacToe.this) { public void
			 * onSuccess(Integer ts) { if (ts == TicTacToeService.tsAny) { if
			 * (gameStatus == TicTacToeService.gsCrossPlaying) {
			 * imgTTT[x][y].setUrl(imgUrlMaybeCross); } else if (gameStatus ==
			 * TicTacToeService.gsNoughtPlaying) {
			 * imgTTT[x][y].setUrl(imgUrlMaybeNought); } } } });
			 */
		}

		public void onMouseOut(MouseOutEvent event)
		{
			/*
			 * final int ts = tileStatus[tttX][tttY];
			 * 
			 * if (ts == TicTacToeService.tsAny) {
			 * imgTTT[x][y].setUrl(imgUrlAny); }
			 */
		}
	}

	public void onFailure(Throwable caught)
	{
		Window.alert(caught.toString() + "|" + caught.getMessage());
	}

	protected Widget getPlayArea()
	{
		return vPanel;
	}
}
